package com.zm.admin.quartz;


import com.zm.admin.zmeng.domain.ZmScheduleJob;
import lombok.NoArgsConstructor;
import org.quartz.*;

/**
 * Quartz 服务
 * <p>
 * @serial 2.0.0
 * @author 就眠儀式
 */
@NoArgsConstructor
public class QuartzService {

    /**
     * 定时任务标识 Key
     */
    private static final String SCHEDULE_NAME = "qrtz_";

    /**
     * 触发器 KEY
     */
    public static TriggerKey getTriggerKey(Long jobId) {
        return TriggerKey.triggerKey(SCHEDULE_NAME + jobId);
    }

    /**
     * 定时器 Key
     */
    public static JobKey getJobKey(Long jobId) {
        return JobKey.jobKey(SCHEDULE_NAME + jobId);
    }

    /**
     * 表达式触发器
     */
    public static CronTrigger getCronTrigger(Scheduler scheduler, Long jobId) {
        try {
            return (CronTrigger) scheduler.getTrigger(getTriggerKey(jobId));
        } catch (SchedulerException e) {
            return null;
        }
    }

    /**
     * Describe: 创建定时任务
     * Param: Scheduler ScheduleJobBean
     * Return: null
     */
    public static void createJob(Scheduler scheduler, ZmScheduleJob scheduleJob) {
        try {
            // 构建定时器
            JobDetail jobDetail = JobBuilder.newJob(QuartzExecute.class).withIdentity(getJobKey(Long.parseLong(scheduleJob.getId()))).build();
            CronScheduleBuilder scheduleBuilder = CronScheduleBuilder
                    .cronSchedule(scheduleJob.getCron())
                    .withMisfireHandlingInstructionDoNothing();
            CronTrigger trigger = TriggerBuilder.newTrigger()
                    .withIdentity(getTriggerKey(Long.parseLong(scheduleJob.getId())))
                    .withSchedule(scheduleBuilder).build();
            jobDetail.getJobDataMap().put(ZmScheduleJob.JOB_PARAM_KEY, scheduleJob);
            scheduler.scheduleJob(jobDetail, trigger);
            // 如果该任务处于暂停状态
            if ("0".equals(scheduleJob.getStatus())) {
                pauseJob(scheduler, Long.parseLong(scheduleJob.getId()));
            }
            // 如果该任务处于删除状态
            if("-1".equals(scheduleJob.getStatus())){
                deleteJob(scheduler,Long.parseLong(scheduleJob.getId()));
            }
        } catch (SchedulerException e) {
            throw new RuntimeException("createJob Fail", e);
        }
    }

    /**
     * Describe: 更新定时任务
     * Param: Scheduler ScheduleJobBean
     * Return: null
     */
    public static void updateJob(Scheduler scheduler, ZmScheduleJob scheduleJob) {
        try {
            TriggerKey triggerKey = getTriggerKey(Long.parseLong(scheduleJob.getId()));
            CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(scheduleJob.getCron()).withMisfireHandlingInstructionDoNothing();
            CronTrigger trigger = getCronTrigger(scheduler, Long.parseLong(scheduleJob.getId()));
            assert trigger != null;
            trigger = trigger.getTriggerBuilder().withIdentity(triggerKey).withSchedule(scheduleBuilder).build();
            trigger.getJobDataMap().put(ZmScheduleJob.JOB_PARAM_KEY, scheduleJob);
            scheduler.rescheduleJob(triggerKey, trigger);
            if ("0".equals(scheduleJob.getStatus())) {
                pauseJob(scheduler, Long.parseLong(scheduleJob.getId()));
            }
        } catch (SchedulerException e) {
            throw new RuntimeException("updateJob Fail", e);
        }
    }

    /**
     * Describe: 停止定时任务
     * Param: Scheduler ScheduleJobBean
     * Return: null
     */
    public static void pauseJob(Scheduler scheduler, Long jobId) {
        try {
            scheduler.pauseJob(getJobKey(jobId));
        } catch (SchedulerException e) {
            throw new RuntimeException("pauseJob Fail", e);
        }
    }

    /**
     * Describe: 恢复定时任务
     * Param: Scheduler ScheduleJobBean
     * Return: null
     */
    public static void resumeJob(Scheduler scheduler, Long jobId) {
        try {
            scheduler.resumeJob(getJobKey(jobId));
        } catch (SchedulerException e) {
            throw new RuntimeException("resumeJob Fail", e);
        }
    }

    /**
     * Describe: 删除定时任务
     * Param: Scheduler ScheduleJobBean
     * Return: null
     */
    public static void deleteJob(Scheduler scheduler, Long jobId) {
        try {
            scheduler.deleteJob(getJobKey(jobId));
        } catch (SchedulerException e) {
            throw new RuntimeException("deleteJob Fail", e);
        }
    }

    /**
     * Describe: 执行定时任务
     * Param: Scheduler ScheduleJobBean
     * Return: null
     */
    public static void run(Scheduler scheduler, ZmScheduleJob scheduleJob) {
        try {
            JobDataMap dataMap = new JobDataMap();
            dataMap.put(ZmScheduleJob.JOB_PARAM_KEY, scheduleJob);
            scheduler.triggerJob(getJobKey(Long.parseLong(scheduleJob.getId())), dataMap);
        } catch (SchedulerException e) {
            throw new RuntimeException("init Fail", e);
        }
    }

}
